﻿using JESAI.Application.Abstractions.Dtos;
using JESAI.Application.Abstractions.Sys;
using JESAI.Application.Abstractions.Sys.Dtos;
using JESAI.Application.Abstractions.Sys.Querys;
using JESAI.AutoMapper.ObjectMapping;
using JESAI.Core.Attributes;
using JESAI.DDD.Dtos;
using JESAI.Platform.Domain.Sys.Entities;
using JESAI.Platform.Domain.Sys.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JESAI.Core.Util.Extensions.Strings;
using JESAI.Core.Util.Helpers;
using JESAI.Core.Extensions;
using Newtonsoft.Json;

namespace JESAI.Application.Service.Sys
{
    [AppService]
    public class FormService : IFormService
    {
        private readonly IFormRepository _formRepository;

        private readonly IFormFieldRepository _formFieldRepository;

        public FormService(IFormRepository formRepository, IFormFieldRepository formFieldRepository)
        {
            _formRepository = formRepository;
            _formFieldRepository = formFieldRepository;
        }

        public async Task AddForm(FormInput formInput)
        {
            var formModel = formInput.MapTo<FormEntity>();
            if (formModel.Id.IsNullOrWhiteSpace())
            {
                formModel.Id = Guid.NewGuid().ToString();
            }

            if (formModel.FormCode.IsNullOrWhiteSpace())
            {
                formModel.FormCode = Guid.NewGuid().ToString();
            }
            formModel.CreateTime = DateTime.Now;
            await _formRepository.InsertAsync(formModel);

            List<FormFieldDto> formFieldDtos = JsonConvert.DeserializeObject<List<FormFieldDto>>(formInput.Rules);
            List<FormFieldEntity> formFieldModels = new List<FormFieldEntity>();
            foreach (var formFieldDto in formFieldDtos)
            {
                var formFieldModel = new FormFieldEntity();
                formFieldModel.Id = Guid.NewGuid().ToString();
                formFieldModel.FormId = formModel.Id;
                formFieldModel.Field = formFieldDto.field;
                formFieldModel.Options = formFieldDto.options;
                formFieldModel.Title = formFieldDto.title;
                formFieldModel.Type = formFieldDto.type;
                formFieldModel.Props = formFieldDto.props?.ToString();
                formFieldModel.Value = formFieldDto.value;
                formFieldModel.Rule = formFieldDto.rule?.ToString();
                formFieldModel.CreateTime = DateTime.Now;
                formFieldModels.Add(formFieldModel);
            }
            if (formFieldModels.Count() > 0)
            {
                await _formFieldRepository.InsertRangeAsync(formFieldModels);
            }
        }

        public async Task DelFormById(string formId)
        {
            await _formRepository.DeleteAsync(p => p.Id == formId);
        }

        public async Task DelFormByIds(string[] formIds)
        {
            await _formRepository.DeleteByIdsAsync(formIds);
        }

        public async Task<PagedDto<FormDto>> GetFormPageList(FormPageQuery formQuery)
        {
            var totalNumber = 0;
            var data = _formRepository._DbQueryable
                 .WhereIF(!formQuery.Name.IsEmpty(), it => it.Name.Contains(formQuery.Name))
                   .WhereIF(!formQuery.FormCode.IsEmpty(), it => it.FormCode.Contains(formQuery.FormCode))
                    .ToPageList(formQuery.PageIndex, formQuery.PageSize, ref totalNumber);

            //.Page(p => true, formQuery.PageIndex, formQuery.PageSize);
            // var count = await _formRepository.CountAsync(p => true);
            return new PagedDto<FormDto>(totalNumber, data.MapTo<List<FormDto>>());
        }

        public async Task UpdateForm(FormInput formInput)
        {
            var formModel = formInput.MapTo<FormEntity>();
            formModel.UpdateTime = DateTime.Now;
            await _formRepository.UpdateAsync(formModel);

            List<FormFieldDto> formFieldDtos = JsonConvert.DeserializeObject<List<FormFieldDto>>(formInput.Rules);
            foreach (var formFieldDto in formFieldDtos)
            {
                var isAdd = false;
                var formFieldModel = _formFieldRepository._DbQueryable.Where(p => p.FormId == formModel.Id && p.Field == formFieldDto.field).ToList().FirstOrDefault();
                if (formFieldModel == null)
                {
                    formFieldModel = new FormFieldEntity();
                    formFieldModel.Id = Guid.NewGuid().ToString();
                    isAdd = true;
                }
                formFieldModel.FormId = formModel.Id;
                formFieldModel.Field = formFieldDto.field;
                formFieldModel.Options = formFieldDto.options;
                formFieldModel.Title = formFieldDto.title;
                formFieldModel.Props = formFieldDto.props?.ToString();
                formFieldModel.Value = formFieldDto.value;
                formFieldModel.Rule = formFieldDto.rule?.ToString();
                formFieldModel.Type = formFieldDto.type;

                if (isAdd)
                {
                    await _formFieldRepository.InsertAsync(formFieldModel);
                }
                else
                {
                    formFieldModel.UpdateTime = DateTime.Now;
                    await _formFieldRepository.UpdateAsync(formFieldModel);
                }

            }
        }

    }
}
